import com.jcraft.jsch.*
import com.jcraft.jcterm.*
import java.util.Map;
import java.awt.Color
import javax.swing.*
import javax.swing.tree.DefaultMutableTreeNode as TreeNode
import org.apache.log4j.*
import net.sshiffon.*
import net.sshiffon.logging.JTableAppender;
import java.awt.event.KeyEvent

import com.wittams.gritty.swing.TermPanel

class SshiffonController {
    // these will be injected by Griffon
    def model
    def view

    void mvcGroupInit(Map<String,Object> args) {
        // this method is called after model and view are injected
        logger.info('Starting main MVC Group')
        model.loadConnections()
        doOutside {
        //	loadNetInterfaces()
        }
    }
    void newConfigGroup()
    {
	    def ts= new Date().getTime()
	    def mvcId= "ConnectionTab_${ts}"
	    def connectionGroup = buildMVCGroup('ConnectionTab',
	        mvcId,
	        mvcId : mvcId,
	        tabs: view.mainTabbedPane,
	        sshiffonController: this,
	        sshiffonModel: model
	     			  )
        view.mainTabbedPane.addTab(
        		  "Connect ...",
        		  view.imageIcon('/crystal16/connect_no.png'),
        		  connectionGroup.view.rootPanel,
        		  "...")
        view.mainTabbedPane.setSelectedIndex(view.mainTabbedPane.getTabCount()-1)
  	      if (connectionGroup.controller.open()) 
  	      {
  	          model.openConnectionTabs.add(connectionGroup)
  	          //model.activeConnectionTab= connectionGroup
  	          activeConnectionChanged(view.mainTabbedPane.getTabCount()-1)
  	          view.clearAction.closure()
  	      } else {
  	          destroyMVCGroup(mvcId)
  	      }

	}
    void setLoggerPanel()
    {
        AppenderSkeleton appender= new JTableAppender( view.statusBar )
        appender.setThreshold(Level.INFO)
        org.apache.log4j.LogManager.getRootLogger().addAppender(appender)
    }
    

    def quit = { evt = null ->
    	app.shutdown()
    }

    
    public void delete(Object[] paths)
    {
        def parentEntry= model.config.connections;
        if(paths.size()==2)
        {
            //delete group
            //check connections in group
            if(model.config.groups.get(paths[1].toString()).size()>0)
            {
                logger.warn("Warning. Moving connections to main group");
            }
             model.config.groups.remove(paths[1].toString())
        } else if(paths.size()==3) {
            //delete connection
             model.config.connections.remove(paths[2].toString())
             if(model.config.groups.get(paths[1].toString())!=null)
             {
            	 model.config.groups.get(paths[1].toString()).removeAll([paths[2].toString()])
             }
        }
        model.activeConnectionTab.controller.refreshConnectionsList()
    }

    public void save(String group, String key, ConnectionSetting setting) //, String user, String host, String port)
    {
        logger.trace("${model.config.groups.get(group)}")
        model.config.connections.put(key, setting.toMap() ) //, [user : user, server : host, port : Integer.parseInt(port)])

        if(!model.config.groups.get(group))
        {
            model.config.groups.put(group,[])
        }
        if(
            !model.config.groups.get(group).contains(key)
        )
        {
            //remove from other groups ...
            model.config.groups.each({ groupname,members ->
                    if(members.contains(key)) members.removeAll([key])
            })
            model.config.groups.get(group).add(key)
        }
        model.activeConnectionTab?.controller?.refreshConnectionsList()
    }

    public void addGroup(String group)
    {
        logger.debug("add group ${group}")
        if(!model.config.groups.containsKey(group))
        {
            model.config.groups.put(group,[])
        }
        model.activeConnectionTab?.controller?.refreshConnectionsList()
    }

    /*
    def action = { evt = null ->
    }
    */

   void activeConnectionChanged(int index)
   {
	   if (model.activeConnectionTab)
	   {
           model.activeConnectionTab.controller.deactivate()
	   }
       model.activeConnectionTab = index == -1 ? null : model.openConnectionTabs[index]
       if (model.activeConnectionTab) {
           model.activeConnectionTab.controller.activate(model.state)
       }  
   }
   void loadNetInterfaces () 
   {
       model.netInterfaces = ['0.0.0.0'] as List<Object>
       Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
       for (NetworkInterface netint : Collections.list(nets))
       {
           Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
           for (InetAddress inetAddress : Collections.list(inetAddresses)) {
               if(inetAddress.getHostAddress().contains("."))
               {
                   logger.debug("interface: ${netint.getDisplayName()}, address ${inetAddress.getHostAddress()}")
                   model.netInterfaces.add(inetAddress.getHostAddress())
               }
           }
       }
   }
   
   void setDisableOnly(item)
   {
	   def connected =  false
	   if(model.activeConnectionTab && model.activeConnectionTab.model)
	   {
		  if(model.activeConnectionTab.model.connected) { connected = true }
	   }
	   view.terminalAction.enabled=  (!item) || 'Terminal'.equals(item) ? false : connected
	   view.configAction.enabled=  (!item) || 'Config'.equals(item) ? false : connected
	   view.sftpAction.enabled=  (!item) || 'Sftp'.equals(item) ? false : connected
   }

   def saveAction = { evt = null ->  
       //model.activeConnection.controller.save()  
   }  
  
   def closeAction = { evt = null ->
   	   int index = view.mainTabbedPane.indexOfComponent(model.activeConnectionTab.view.rootPanel)
       int index2 = model.openConnectionTabs.indexOf(model.activeConnectionTab)
   	   logger.debug("attempting to close connection Tab: ${index} activeConnection: ${index2}")
       if(index>-1)
       {
        	   view.mainTabbedPane.removeTabAt(index)
    		   setDisableOnly(null)             
        	   if(model.openConnectionTabs.get(index2)!=null)
        	   {
        		   def tab= model.openConnectionTabs.remove(index2)
        		   if(tab)
        		   {
        			   tab.controller.quit()
        			   
        		   }
        	   }
        	   selectTab(index)
       } else {
    	   logger.warn("no tabs selected  ... try to set 0")
    	   selectTab(index)
    	   if(model.activeConnectionTab)
    	   {
    		   index = view.mainTabbedPane.indexOfComponent(model.activeConnectionTab.view.rootPanel)
        	   if(index>-1)
        	   {
        		   closeAction()
        	   }
    	   }
       }
   } 

   /**
    * this method is just called when you're removing a tab
    */
   void selectTab(int index)
   {
	   if (view.mainTabbedPane.getTabCount()>0) {
		   if(view.mainTabbedPane.getTabCount()<=index)
		   {
			   index= view.mainTabbedPane.getTabCount()-1
		   }
		   view.mainTabbedPane.setSelectedIndex(index)
		   model.openConnectionTabs.getAt(index).controller.activate()
	   }  else {
		  //no tabs left to select. make a new one!
		   
		   newConfigGroup()
	   }
   }
}